using Cysharp.Threading.Tasks;
using MoonFramework;
using MoonFramework.Scripts.Event;
using UnityEngine;
using UnityEngine.EventSystems;

namespace UI
{
    public static class UITool
    {
        private static bool _Token = true;

        /// <summary>
        ///     绑定鼠标效果
        /// </summary>
        /// <param name="component">组件</param>
        public static void BindMouseEffect(this Component component)
        {
            //鼠标进入后放大
            component.OnMouseEnter(MouseEffect, component, false, component.transform.localScale);
            //鼠标离开后恢复正常
            component.OnMouseExit(MouseEffect, component, true, component.transform.localScale);
        }

        /// <summary>
        ///     鼠标效果
        /// </summary>
        /// <param name="arg1"></param>
        /// <param name="args">参数列表</param>
        private static void MouseEffect(PointerEventData arg1, object[] args)
        {
            var component = (Component)args[0];
            var isNormal = (bool)args[1];
            var normalScale = (Vector3)args[2];
            _Token = true;
            GameManger.Instance.SetCursorState(isNormal ? CursorState.Normal : CursorState.Handle);
            DoMouseEffect(component, isNormal, normalScale).Forget();
        }

        public static void RemoveMouseEffect(this Component component)
        {
            //手动触发一次退出
            var listener = component.GetComponent<EventListener>();
            if (listener) listener.OnPointerExit(null);
            component.RemoveMouseEnter(MouseEffect);
            component.RemoveMouseExit(MouseEffect);
            _Token = false;
            GameManger.Instance.SetCursorState(CursorState.Normal);
        }

        private static async UniTaskVoid DoMouseEffect(Component component, bool targetIsNormal, Vector3 normalScale)
        {
            var transform = component.transform;
            var curScale = transform.localScale;
            //缩小
            if (targetIsNormal)
            {
                var targetScale = normalScale;
                while (transform.localScale.x > targetScale.x)
                {
                    if (!_Token) break;
                    await UniTask.Yield();
                    if (!transform) break;
                    curScale -= Time.deltaTime * 2 * Vector3.one;
                    transform.localScale = curScale;
                }

                transform.localScale = normalScale;
            }
            else
            {
                var targetScale = normalScale * 1.1f;
                while (transform.localScale.x < targetScale.x)
                {
                    if (!_Token) break;
                    await UniTask.Yield();
                    if (!transform) break;
                    curScale += Time.deltaTime * 2 * Vector3.one;
                    transform.localScale = curScale;
                }

                transform.localScale = normalScale;
            }
        }
    }
}